<template>
  <div class="mall_page">
    <div class="mall_content gl_clear">
      <!-- 菜单 -->
      <ul class="mall_menu gl_fl">
        <li
          v-for="(item, index) in menuInfo"
          :key="index"
          :class="{active:menu.active === index}"
          class="mall_menu_item gl_ellipsis"
          @click="changeMenu(index)"
        >
          {{ item.name }}
        </li>
      </ul>

      <!-- 商品 -->
      <div class="mall_goods gl_clear">
        <div>
          <div class="goods_title gl_clear">
            <span class="gl_fl">商品详情</span>
          </div>
          <div v-loading="loading" class="goods_attr gl_clear">
            <!-- 商品轮播 -->
            <div :key="1" class="goods_swiper gl_fl">
              <!-- swiper1 -->
              <swiper ref="swiperTop" class="swiper gallery-top" :options="swiperOptionTop">
                <swiper-slide v-for="(item, index) in goodsInfo.images" :key="index">
                  <img class="slide_img" :src="getStaticFileUrl(item.imageUrl)">
                </swiper-slide>
              </swiper>
              <!-- swiper2 Thumbs -->
              <div class="thumbs_wrap">
                <swiper ref="swiperThumbs" class="swiper gallery-thumbs" :options="swiperOptionThumbs">
                  <swiper-slide v-for="(item, index) in goodsInfo.images" :key="index">
                    <img class="slide_img" :src="getStaticFileUrl(item.imageUrl)">
                  </swiper-slide>
                </swiper>
                <div class="swiper-button-next swiper-button-black goods_sbn" />
                <div class="swiper-button-prev swiper-button-black goods_sbp" />
              </div>
            </div>

            <!-- 商品属性选择 -->
            <div class="goods_right">
              <div class="attr_title">{{ goodsInfo.name }}</div>
              <ul class="attr_label_wrap">
                <li class="gl_mb_15 gl_clear">
                  <div class="attr_label price gl_fl">价格</div>
                  <div class="attr_price gl_fl">¥ {{ showActiveAttrInfo.id ? formatMoney(showActiveAttrInfo.price) : formatMoney(goodsInfo.price) }}</div>
                </li>
                <li v-show="goodsInfo.colors && goodsInfo.colors.length" class="gl_mb_15 gl_clear">
                  <div class="attr_label color gl_fl">颜色分类</div>
                  <div class="attr_color">
                    <div
                      v-for="(item, index) in goodsInfo.colors"
                      :key="index"
                      :class="{'active': activeColorId === item.id,'cur_disabled': currentSizeAllColor[item.id] && currentSizeAllColor[item.id].count === 0, 'no_img': !colorImgFromInventories[item.id] }"
                      class="attr_color_item gl_fl"
                      @click="chooseGoodsColor(item)"
                    >
                      <img v-if="colorImgFromInventories[item.id]" class="attr_color_img gl_mr_5" :src="getStaticFileUrl(colorImgFromInventories[item.id])">
                      <span>{{ item.name }}</span>
                    </div>
                  </div>
                </li>
                <li v-show="goodsInfo.sizes && goodsInfo.sizes.length" class="gl_mb_15 gl_clear">
                  <div class="attr_label size gl_fl">尺码选择</div>
                  <div class="attr_size">
                    <div
                      v-for="(item, index) in goodsInfo.sizes"
                      :key="index"
                      :class="{'active': activeSizeId === item.id,'cur_disabled': currentColorAllSize[item.id] && currentColorAllSize[item.id].count === 0 }"
                      class="attr_size_item gl_fl"
                      @click="chooseGoodsSize(item)"
                    >
                      {{ item.name }}
                    </div>
                  </div>
                </li>
                <li class="gl_mb_15 gl_clear">
                  <div class="attr_label num gl_fl">数量</div>
                  <div class="attr_num gl_fl">
                    <el-input-number v-model="buyNum" controls-position="right" :min="1" :max="showActiveAttrInfo.id ? showActiveAttrInfo.count : goodsInfo.count" />
                    <span class="attr_inventory">库存：{{ showActiveAttrInfo.id ? showActiveAttrInfo.count : goodsInfo.count }}件</span>
                  </div>
                </li>
              </ul>
              <div class="attr_ctrl gl_clear">
                <div class="attr_btn cart gl_fl" @click="addToCart">加入购物车</div>
                <div class="attr_btn buy gl_fl" @click="toBuy">立即购买</div>
              </div>
            </div>
          </div>
        </div>

        <div>
          <!-- 推荐商品 -->
          <div v-if="showRecommendInfo.length" class="mr_50 gl_fl">
            <div class="goods_title gl_clear">
              <span class="gl_fl">推荐商品</span>
            </div>
            <ul class="gl_py_15">
              <li v-for="(item, index) in showRecommendInfo" :key="index" class="goods_item gl_mb_20" @click="jumpToGoodsDetail(item.productId, item)">
                <div class="goods_item_imgWrap">
                  <template v-if="item.product.images[0]">
                    <img class="goods_item_img" :src="getStaticFileUrl(item.product.images[0].imageUrl)">
                  </template>
                </div>
                <div class="goods_item_price">
                  <span class="goods_yuan">￥</span>
                  <span>{{ formatMoney(item.product.price) }}</span>
                </div>
                <div class="goods_item_desc">{{ item.product.name }}</div>
              </li>
            </ul>
          </div>
          <!-- 商品详情 -->
          <div class="main_goods gl_clear">
            <div class="goods_title gl_clear">
              <span class="gl_fl">商品详情</span>
            </div>
            <div v-loading="loading" class="main_detail gl_px_10">
              <ul v-if="goodsInfo.properties && goodsInfo.properties.length" class="base_info gl_clear">
                <li v-for="(item, index) in goodsInfo.properties" :key="index" class="gl_ellipsis gl_fl">{{ item.name }}：{{ item.value }}</li>
              </ul>
              <div class="main_goods_desc gl_pb_20" v-html="goodsInfo.description" />
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { mapState, mapActions } from 'vuex';
import { getToken } from '@/lib/auth';
import { loginOidc } from '@/lib/oidc_fun';
import {
  api_GET_MallProductId, // 获取指定商品
  api_POST_MallShoppingCart // 添加购物车
} from '@/extend/api/shoppingmallswaggerApi/app.js';
import { postLoginMsg } from '@/lib/index';

export default {
  props: {
    shopInfo: {
      type: Object,
      default() {
        return {};
      }
    },
    menuInfo: {
      type: Array,
      default() {
        return [];
      }
    },
    recommendInfo: {
      type: Array,
      default() {
        return [];
      }
    }
  },
  data () {
    return {
      menu: {
        active: 0
      },
      swiperOptionTop: { // 大轮播图配置
        init: false
        // loop: true, // 不可使用loop,组件复用时会出现问题
        // loopedSlides: 5 // loopedSlides要保持一致
      },
      swiperOptionThumbs: { // 小轮播图配置
        init: false,
        // loop: true, // 不可使用loop,组件复用时会出现问题
        // loopedSlides: 5, // loopedSlides要保持一致
        centeredSlides: true,
        slidesPerView: 5,
        touchRatio: 0.2,
        slideToClickedSlide: true,
        spaceBetween: 5,
        navigation: {
          nextEl: '.swiper-button-next',
          prevEl: '.swiper-button-prev'
        }
      },
      goodsId: '', // 商品ID
      goodsInfo: {}, // 商品详情
      buyNum: 1, // 购买数量
      activeColorId: '', // 选择的颜色id
      activeSizeId: '', // 选择的尺码id
      activeColor: '', // 选择的颜色
      activeSize: '', // 选择的尺码
      addCartLoading: false,
      loading: false,
      registerId: ''
    };
  },
  computed: {
    ...mapState({
      vxCurrentUserType: state => state.user.currentUserType,
      tokenInfo: state => state.user.token || getToken()
    }),
    vxRegisterId () {
      return this.vxCurrentUserType ? this.vxCurrentUserType.registerId : '';
    },
    showRecommendInfo () { // 页面展示的
      return this.recommendInfo.filter(item => item.productId !== this.goodsId);
    },
    showActiveAttrInfo () { // 展示用户选择商品尺码及颜色后的相关信息数据，如价格及库存数量
      const _list = this.goodsInfo.inventories || [];

      const _findData = _list.find(item => {
        if (this.isNeedColor && this.isNeedSize) {
          // 商品需要选择颜色和尺码
          return item.productSizeId === this.activeSizeId && item.productColorId === this.activeColorId;
        } else if (this.isNeedColor && !this.isNeedSize) {
          // 商品仅需要选择颜色
          return item.productColorId === this.activeColorId;
        } else if (!this.isNeedColor && this.isNeedSize) {
          // 商品仅需要选择尺码
          return item.productSizeId === this.activeSizeId;
        }
      });
      return _findData || {};
    },
    colorImgFromInventories () { // 通过库存数据处理颜色图片
      const returnData = {};
      const _list = this.goodsInfo.inventories || [];
      for (let i = 0; i < _list.length; i++) {
        const item = _list[i];
        if (item.productColorId in returnData) {
          continue;
        }
        returnData[item.productColorId] = item.imageUrl;
      }
      return returnData;
    },
    // 当前选中颜色的所有尺码
    currentColorAllSize () {
      const _list = this.goodsInfo.inventories || [];
      const returnData = {};
      for (let i = 0; i < _list.length; i++) {
        const item = _list[i];
        if (item.productColorId === this.activeColorId) {
          returnData[item.productSizeId] = item;
        }
      }
      return returnData || {};
    },
    // 当前选中尺码的所有颜色
    currentSizeAllColor () {
      const _list = this.goodsInfo.inventories || [];
      const returnData = {};
      for (let i = 0; i < _list.length; i++) {
        const item = _list[i];
        if (item.productSizeId === this.activeSizeId) {
          returnData[item.productColorId] = item;
        }
      }
      return returnData || {};
    },
    menuIndexByIdMap () { // 组合menuIndexId: {menuId: index}
      const returnData = {};
      for (let i = 0; i < this.menuInfo.length; i++) {
        const item = this.menuInfo[i];
        returnData[item.id] = i;
      }
      return returnData;
    },
    // 商品是否需要颜色
    isNeedColor () {
      return Boolean(this.goodsInfo.colors.length);
    },
    // 商品是否需要尺码
    isNeedSize () {
      return Boolean(this.goodsInfo.sizes.length);
    },
    tenantId() {
      const _ids = this.$route.params.id.split('_');
      return _ids[1] && _ids[1] !== 'plat' ? _ids[1] : '';
    }
  },
  watch: {
    $route() {
      this.init();
    }
  },
  created () {
    this.init();
  },
  methods: {
    ...mapActions({ setBuyGoods: 'app/setBuyGoods' }),
    init () {
      // 处理菜单选中项
      this.menu.active = Number(this.$route.query.active) || 0;
      // 获取商品详情
      this.goodsId = this.$route.params.goodsId;
      this.getGoodsInfo(this.goodsId, {
        IncludeImages: true,
        IncludeProperties: true,
        IncludeDescription: true,
        IncludeColors: true,
        IncludeSizes: true,
        IncludeInventories: true,
        IncludeGroup: true,
        IncludeStatus: true
      });
    },
    goLogin() {
      const tenantId = this.tenantId + '___' + ENVIR;
      let href = window.location.href;
      href =
        href.indexOf('#') > -1
          ? href.indexOf('?') > -1
            ? href + '&'
            : href + '?'
          : href + '#/?';
      href = href
        .replace(/loginRandom=[0-9]+|loginRandom=/g, '')
        .replace(/&&+/g, '&')
        .replace('?&', '?');
      href = href + 'loginRandom=' + new Date().getTime();
      // 跳转登录
      loginOidc({
        state: window.btoa(href),
        acr_values: tenantId ? window.btoa(tenantId) : ''
      });
    },
    // 获取商品详细信息
    getGoodsInfo (id, qo) {
      this.loading = true;
      api_GET_MallProductId(id, qo)
        .then(
          res => {
            this.loading = false;
            if (res && res.id) {
              // 过滤出有效尺码
              this.filterGoodsSize(res);
              // 排序商品中的颜色、尺码、图片等
              this.sortGoodsInfo(res);
              // 默认选中商品的第一个颜色 第一个尺码
              this.chooseGoodsFirstSizeAndFirstColor(res);
              this.goodsInfo = res;
              // 轮播处理
              this.$nextTick(() => {
                const swiperTop = this.$refs.swiperTop.swiper;
                const swiperThumbs = this.$refs.swiperThumbs.swiper;
                swiperTop.controller.control = swiperThumbs;
                swiperThumbs.controller.control = swiperTop;
                swiperTop.init();
                swiperThumbs.init();
              });
            }
          }
        )
        .catch(
          () => {
            this.loading = false;
          }
        );
    },
    filterGoodsSize (data) {
      if (data.sizes && data.sizes.length) {
        data.sizes = data.sizes.filter(item => item.isSelected);
      }
    },
    sortGoodsInfo (data) {
      if (data.sizes && data.sizes.length) {
        data.sizes.sort((a, b) => a.sortOrder - b.sortOrder);
      }
      if (data.colors && data.colors.length) {
        data.colors.sort((a, b) => a.sortOrder - b.sortOrder);
      }
      if (data.images && data.images.length) {
        data.images.sort((a, b) => a.sortOrder - b.sortOrder);
      }
      if (data.properties && data.properties.length) {
        data.properties.sort((a, b) => a.sortOrder - b.sortOrder);
      }
    },
    // 默认选中商品的第一个颜色第一个尺码
    chooseGoodsFirstSizeAndFirstColor (data) {
      // 组合颜色和尺码，查看是否有库存，有库存则选中。没有则不选
      const _inventories = data.inventories || [];
      const _colors = data.colors || [];
      const _sizes = data.sizes || [];
      for (let i = 0; i < _colors.length; i++) {
        const item = _colors[i];
        for (let j = 0; j < _sizes.length; j++) {
          const jtem = _sizes[j];
          const _curColorId = item.id;
          const _curSizeId = jtem.id;
          for (let k = 0; k < _inventories.length; k++) {
            const ktem = _inventories[k];
            if (ktem.productColorId === _curColorId && ktem.productSizeId === _curSizeId && ktem.count) {
              this.activeColorId = ktem.productColorId;
              this.activeSizeId = ktem.productSizeId;
              this.activeColor = item;
              this.activeSize = jtem;
              return;
            }
          }
        }
      }
    },
    // 选择颜色
    chooseGoodsColor (data) {
      this.buyNum = 1;
      if (data.id in this.currentSizeAllColor) {
        if (this.currentSizeAllColor[data.id].count !== 0) {
          this.activeColorId = data.id;
          this.activeColor = data;
        }
      } else {
        this.activeColorId = data.id;
        this.activeColor = data;
      }
    },
    // 选择尺码
    chooseGoodsSize (data) {
      this.buyNum = 1;
      if (data.id in this.currentColorAllSize) {
        if (this.currentColorAllSize[data.id].count !== 0) {
          this.activeSizeId = data.id;
          this.activeSize = data;
        }
      } else {
        this.activeSizeId = data.id;
        this.activeSize = data;
      }
    },
    // 切换菜单
    changeMenu (index) {
      this.menu.active = index;
      const _query = Object.assign({}, this.$route.query);
      _query.active = index;
      if (this.shopInfo.route) {
        this.$router.push({
          path: `/home/${this.$route.params.id}`,
          query: _query
        });
      }
    },
    // 跳转至商品详情页
    jumpToGoodsDetail (goodsId, data) {
      // 合并原有Query
      const _query = Object.assign({}, this.$route.query);
      // 根据商品的groupId 传递active
      const _active = data.product.group.id;
      _query.active = this.menuIndexByIdMap[_active];
      const _parms = this.$route.params;
      _parms['goodsId'] = goodsId;
      this.$router.push({
        name: 'MallDetail',
        params: _parms,
        query: _query
      });
    },
    // 加入购物车
    addToCart () {
      const _canBuy = this.checkCanBuy();
      if (_canBuy) {
        this.addCartLoading = true;
        api_POST_MallShoppingCart({
          productId: this.goodsId,
          color: this.activeColor ? this.activeColor.name : null,
          size: this.activeSize ? this.activeSize.name : null,
          count: this.buyNum,
          registerId: this.vxRegisterId,
          storeId: this.shopInfo.id
        })
          .then(
            res => {
              this.$message({
                message: `添加购物车成功`,
                type: 'success',
                showClose: true
              });
              this.$emit('reGetCartInfo');
              this.addCartLoading = false;
            }
          )
          .catch(
            error => {
              this.$message({
                message: `添加购物车失败 ${error.error.message}`,
                type: 'error',
                showClose: true
              });
              console.log('error: ', error);
              this.addCartLoading = false;
            }
          );
      }
    },
    // 立即购买
    toBuy () {
      const _canBuy = this.checkCanBuy();
      if (_canBuy) {
        this.setBuyGoods({
          count: this.buyNum,
          productId: this.goodsId,
          color: this.activeColor,
          size: this.activeSize
        });
        this.$router.push({
          name: 'Settlement'
        });
      }
    },
    // 校验是否可以购买，用户是否选择了颜色尺码及商品数量
    checkCanBuy () {
      // 需要登录
      if (this.tokenInfo) {
        // 找到token，未找到RegisterId
        // if (!this.vxRegisterId) {
        //   this.$message({
        //     message: `请先前往个人中心完善个人信息`,
        //     type: 'warning',
        //     showClose: true
        //   });
        //   return false;
        // }
      } else {
        // 嵌入式
        if (this.$route.params.id.indexOf('_plat') === -1) {
          postLoginMsg();
          return false;
        }
        // 非嵌入式
        // 未找到token,需要登录
        this.goLogin();
        return false;
      }
      // 如果商品有颜色分类，必须选一个
      if (this.isNeedColor && !this.activeColorId) {
        this.$message({
          message: `请选择您要购买的颜色`,
          type: 'warning',
          showClose: true
        });
        return false;
      }
      // 如果商品有尺码分类，必须选一个
      if (this.isNeedSize && !this.activeSizeId) {
        this.$message({
          message: `请选择您要购买的尺码`,
          type: 'warning',
          showClose: true
        });
        return false;
      }
      if (this.goodsInfo && !this.goodsInfo.count) {
        this.$message({
          message: `商品已经售罄了`,
          type: 'warning',
          showClose: true
        });
        return false;
      }

      if (this.showActiveAttrInfo && this.showActiveAttrInfo.id && !this.showActiveAttrInfo.count) {
        this.$message({
          message: `您选择的商品已经售罄了`,
          type: 'warning',
          showClose: true
        });
        return false;
      }
      return true;
    },
    // 格式化货币格式 （分）
    formatMoney (num) {
      if (typeof num === 'number' && !Number.isNaN(num)) {
        // num 是数字类型 且不是 NaN
        let strNum = String(num); // 金额文本类型
        if (num >= 0) {
          strNum = strNum.padStart(3, '0'); // 用0填充保证最小三位数
          const _floatNum = strNum.slice(-2);
          if (Number(_floatNum)) {
            return strNum.slice(0, -2) + '.' + _floatNum; // 金额拼接
          } else {
            return strNum.slice(0, -2);
          }
        } else {
          const _mark = strNum.slice(0, 1); // 负号
          const _noMark = strNum.slice(1); // 无负号数值
          strNum = _noMark.padStart(3, '0'); // 用0填充保证最小三位数
          const _floatNum = strNum.slice(-2);
          if (Number(_floatNum)) {
            return _mark + strNum.slice(0, -2) + '.' + _floatNum; // 金额拼接
          } else {
            return _mark + strNum.slice(0, -2);
          }
        }
      } else {
        return '';
      }
    },
    // 将元转化为分
    yuanToFen (moneyStr) {
      const _moneyStr = String(moneyStr);
      const yuan = Number(_moneyStr.split('.')[0]) || 0;
      const fen = Number(_moneyStr.split('.')[1]) || 0;
      return yuan * 100 + fen;
    },
    // 获取静态文件
    getStaticFileUrl (relativeUrl) {
      if (!relativeUrl) return '';
      return WEB_CONFIG.VUE_APP_STATIC_FILE_RUL + relativeUrl;
    }
  }
};
</script>

<style>
  .main_goods_desc img {
    max-width: 100% !important;
  }
</style>

<style lang="scss" scoped>
  .mall_goods {
    padding-top: 20px;
    margin-left: 210px;
  }

  .mr_50 {
    margin-right: 50px;
  }

  .base_info {
    padding: 20px 0;
    line-height: 20px;
    font-size: 14px;
    font-weight: 400;
    color: #353434;
    li {
      width: 220px;
      margin-right: 20px;
      margin-bottom: 20px;
    }
  }

  .goods_attr {
    padding-top: 10px;
    padding-bottom: 40px;
    overflow: hidden;
  }
  .goods_right {
    margin-left: 284px;
  }

  // swiper
  .goods_swiper {
    width: 270px;
    // height: 310px;
  }
  .thumbs_wrap {
    position: relative;
    padding: 0 20px;
    height: 40px;
    .swiper-slide {
      // background-color: #000;
      box-sizing: border-box;
      border: 1px solid rgb(240, 240, 240);
      background-size: cover;
      background-position: center;
    }
  }
  .swiper {
    .swiper-slide {
      background-size: cover;
      background-position: center;
    }

    &.gallery-top {
      height: 270px;
      width: 100%;
      margin-bottom: 6px;
    }
    &.gallery-thumbs {
      height: 40px;
      box-sizing: border-box;
    }
    &.gallery-thumbs .swiper-slide img {
      // width: 25%;
      // height: 100%;
      opacity: 0.76;
    }
    &.gallery-thumbs .swiper-slide-active img {
      opacity: 1;
    }
  }
  .slide_img {
    width: 100%;
    height: 100%;
  }
  .goods_sbp {
    width: 15px;
    left: 0;
  }
  .goods_sbn {
    width: 15px;
    right: 0;
  }
  .swiper-button-prev:after,
  .swiper-button-next:after {
    font-size: 16px;
  }

  .attr_label_wrap {
    overflow: hidden;
  }
  .attr_btn {
    padding: 10px 20px;
    font-size: 14px;
    font-weight: 400;
    color: #ffffff;
    line-height: 22px;
    border-radius: 4px;
    cursor: pointer;
  }
  .attr_btn.cart {
    background-color: #E02020;
  }
  .attr_btn.buy {
    background-color: #1890FF;
  }
  .attr_btn+.attr_btn {
    margin-left: 18px;
  }

  .attr_title {
    font-size: 16px;
    font-weight: 500;
    line-height: 22px;
    color: #353434;
    margin-bottom: 15px;
  }
  .attr_label {
    width: 70px;
    font-size: 14px;
    font-weight: 400;
    color: #828282;
  }
  .attr_label.price {
    line-height: 28px;
  }
  .attr_label.num {
    line-height: 40px;
  }
  .attr_label.color {
    line-height: 44px;
  }
  .attr_label.size {
    line-height: 36px;
  }
  .attr_price {
    font-size: 16px;
    font-weight: 400;
    line-height: 28px;
    color: #e02020;
  }
  .attr_size,
  .attr_color {
    margin-left: 70px;
  }
  .attr_size_item {
    padding: 7px 20px;
    line-height: 20px;
    font-size: 14px;
    color: #666;
    border-radius: 2px;
    border: 1px solid #ccc;
    margin-right: 10px;
    margin-bottom: 5px;
    cursor: pointer;
  }
  .attr_color_item {
    padding: 3px 10px 3px 3px;
    line-height: 36px;
    font-size: 14px;
    color: #666;
    border-radius: 2px;
    border: 1px solid #ccc;
    margin-right: 10px;
    margin-bottom: 5px;
    cursor: pointer;
  }
  .attr_color_item.no_img {
    padding-left: 10px;
  }
  .attr_color_img {
    width: 36px;
    height: 36px;
    vertical-align: middle;
  }
  .attr_color_item.active,
  .attr_size_item.active {
    border: 1px solid #e33a3c;
  }
  .attr_inventory {
    line-height: 20px;
    font-size: 14px;
    font-weight: 400;
    color: #828282;
    padding-left: 24px;
  }
  .cur_disabled {
    cursor: not-allowed;
    color: #ccc;
  }
  .main_detail {
    min-height: 300px;
    position: relative;
  }
</style>
